home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-26 | 5.7 KB | 177 lines | [TEXT/CCL2] |
- ;;; -*- Mode: Lisp; Syntax: Common-Lisp; Package: CL-USER; -*-
-
- (in-package :cl-user)
-
- #|
-
- Proportion-bar defines a subclass of simple-view that shows a bar in which the size
- of each of k regions is proportional to the magnitude of some parameter. This can be
- used, for example, to show the relative likelihoods of a set of mutually exclusive
- and exhaustive possibilities. The methods used by this are:
-
- proportion-bar-n v -- number of values to be displayed
- proportion-bar-val v i -- i'th value, on a scale from 0.0 to 1.0; all must sum to 1.0
- proportion-bar-pat v i -- pen pattern for this value; defaults to a selection from
- {white, light-gray, gray, dark-gray, black} patterns
- proportion-bar-color v i -- color value (as in make-color) for the bar; default black
-
- |#
-
- (export '(proportion-bar))
-
- (defclass proportion-bar (simple-view)
- ()
- )
-
- (defmethod proportion-bar-n ((v proportion-bar))
- 1)
-
- (defmethod proportion-bar-val ((v proportion-bar) i)
- (declare (ignore i))
- (/ 1.0 (proportion-bar-n v)))
-
- (defparameter *defined-patterns*
- (list *white-pattern* *light-gray-pattern* *gray-pattern*
- *dark-gray-pattern* *black-pattern*))
-
- (defmethod proportion-bar-pat ((v proportion-bar) i)
- (let ((n (proportion-bar-n v)))
- (assert (> n 0) (n) "Proportion-bar-n of ~s (~d) must be > 0." v n)
- (case n
- (1 *black-pattern*)
- (2 (if (zerop i) *white-pattern* *black-pattern*))
- (3 (ccase i
- (0 *white-pattern*)
- (1 *gray-pattern*)
- (2 *black-pattern*)))
- (4 (ccase i
- (0 *white-pattern*)
- (1 *light-gray-pattern*)
- (2 *dark-gray-pattern*)
- (3 *black-pattern*)))
- (otherwise (nth (mod i 5) *defined-patterns*)))))
-
- (defmethod proportion-bar-color ((v proportion-bar) i)
- (declare (ignore i))
- *black-color*)
-
- (defmethod view-draw-contents ((v proportion-bar))
- (let* ((sz (view-size v))
- (s-h (point-h sz))
- (s-v (point-v sz))
- (n (proportion-bar-n v))
- (horiz? (> s-h s-v))
- (max (if horiz? s-h s-v))
- )
- (with-focused-view v
- (rlet ((r :rect))
- (do ((i 0 (1+ i))
- (cum 0.0)
- (beg 0 end)
- (end))
- ((>= i n))
- (declare (float cum))
- (setq end (round (* max (setq cum (+ cum (proportion-bar-val v i))))))
- (setf (pref r rect.topleft)
- (if horiz? (make-point beg 0) (make-point 0 beg)))
- (setf (pref r rect.bottomright)
- (if horiz? (make-point end s-v) (make-point s-h end)))
- (with-fore-color (proportion-bar-color v i)
- (#_FillRect r (proportion-bar-pat v i)))
- (cond (horiz? (#_MoveTo beg 0) (#_LineTo beg s-v))
- (t (#_MoveTo 0 beg) (#_LineTo s-h beg))))
- (setf (pref r rect.topleft) #@(0 0))
- (setf (pref r rect.bottomright) sz)
- (#_FrameRect r)))))
-
- #| A very simple example:
-
- ;; Initially, we just define a vertical and a horizontal bar, using the default
- ;; pattern selections for display.
-
- (defclass example-bar (proportion-bar)
- ((vals :accessor vals :initarg :vals)))
-
- (defmethod proportion-bar-n ((b example-bar))
- (length (vals b)))
-
- (defmethod proportion-bar-val ((b example-bar) i)
- (nth i (vals b)))
-
- (defmethod initialize-instance :after ((b example-bar) &rest foo)
- (declare (ignore foo))
- (let ((tot (float (apply #'+ (vals b)))))
- (do ((vl (vals b) (cdr vl)))
- ((null vl))
- (setf (car vl) (/ (car vl) tot)))
- b))
-
- (defparameter w (make-instance 'window
- :window-title "Proportion-bar test"
- :color-p t))
-
- (defparameter b1 (make-instance 'example-bar
- :view-size #@(16 50)
- :view-position #@(3 3)
- :vals '(1 2 3 4)))
-
- (defparameter b2 (make-instance 'example-bar
- :view-size #@(100 16)
- :view-position #@(29 3)
- :vals '(3 5)))
-
- (add-subviews w b1 b2)
-
- ;; Here we add overall color to the bar class; we get just a normal bar, except
- ;; all in the specified color.
-
- (defclass color-example-bar (example-bar)
- ((color :accessor color :initarg :color)))
-
- (defmethod proportion-bar-color ((v color-example-bar) i)
- (declare (ignore i))
- (color v))
-
- (defmethod view-draw-contents ((v color-example-bar))
- (with-fore-color (color v)
- (call-next-method)))
-
- (defparameter b3 (make-instance 'color-example-bar
- :view-size #@(200 30)
- :view-position #@(40 50)
- :color *red-color*
- :vals '(.1 .2 .1 .2 .1 .1 .2)))
-
- (add-subviews w b3)
-
- ;; Finally, we create a bar whose regions are drawn in various solid shades of the
- ;; given color, instead of in patterns.
-
- (defclass shade-example-bar (color-example-bar) ())
-
- (defmethod proportion-bar-pat ((v shade-example-bar) i)
- (declare (ignore i))
- *black-pattern*)
-
- (defmethod proportion-bar-color ((v shade-example-bar) i)
- (let* ((col (color v))
- (cr (color-red col))
- (cg (color-green col))
- (cb (color-blue col))
- (n (proportion-bar-n v))
- (mul (if (= n 1) 1.0 (/ (float i) (1- n)))))
- ;; Note that 65280 is the magic number that is the intensity of r, g and b
- ;; in *white-color*; in principle this should be 65536 (according to the manual)
- ;; but that doesn't work, at least in MCL 2.0f2.
- (flet ((interp (c) (+ 65280 (round (* mul (- c 65280))))))
- (make-color (interp cr) (interp cg) (interp cb)))))
-
- (defparameter b4 (make-instance 'shade-example-bar
- :view-size #@(200 20)
- :view-position #@(30 100)
- :color *dark-green-color*
- :vals '(.1 .2 .1 .2 .1 .1 .2)))
-
- (add-subviews w b4)
-
- |#